
using System;
using System.Runtime.InteropServices;
using System.Net;
using System.Windows.Forms;
using System.Drawing;

using DirectShowLib;
using DirectShowLib.Utils;
// Add a reference to IGlobalist.Net.Rtp.dll
// Classes used - RtpSession, RtpSender, RtpParticipant, RtpStream
using IGlobalist.Net.Rtp;

namespace IGlobalist
{
    /// <summary> Summary description for MainForm. </summary>
    internal class ShowAudio : IDisposable
    {
        #region Member variables

        /// <summary> graph builder interface. </summary>
        private IFilterGraph2 m_FilterGraph = null;
        IMediaControl m_mediaCtrl = null;

        /// <summary> Set by async routine when it captures an image </summary>
        private bool m_bRunning = false;

#if DEBUG
        DsROTEntry m_rot = null;
#endif

        #endregion

        /// <summary> release everything. </summary>
        public void Dispose()
        {
            GC.SuppressFinalize(this);
            CloseInterfaces();
        }

        ~ShowAudio()
        {
            Dispose();
        }

        /// <summary>
        /// Create capture object
        /// </summary>
        /// <param name="iDeviceNum">Zero based index of capture device</param>
        /// <param name="szFileName">Output ASF file name</param>
        public ShowAudio(RtpStream rtpStream)
        {


            try
            {
                // Set up the capture graph
                SetupGraph(rtpStream);

                m_bRunning = false;
            }
            catch
            {
                Dispose();
                throw;
            }
        }


        // Start the capture graph
        public void Start()
        {
            if (!m_bRunning)
            {
                int hr = m_mediaCtrl.Run();
                Marshal.ThrowExceptionForHR(hr);

                m_bRunning = true;
            }
        }

        // Pause the capture graph.
        // Running the graph takes up a lot of resources.  Pause it when it
        // isn't needed.
        public void Pause()
        {
            if (m_bRunning)
            {
                IMediaControl mediaCtrl = m_FilterGraph as IMediaControl;

                int hr = mediaCtrl.Pause();
                Marshal.ThrowExceptionForHR(hr);

                m_bRunning = false;
            }
        }

        /// <summary> build the capture graph. </summary>
        private void SetupGraph(RtpStream rtpStream)
        {
            int hr;

            IBaseFilter rtpSrcFilter = null;
            IBaseFilter render = null;
            RtpFilters.IRtpSource rtpSource = null;
            ICaptureGraphBuilder2 capGraph = null;

            // Get the graphbuilder object
            m_FilterGraph = (IFilterGraph2)new FilterGraph();

#if DEBUG
            m_rot = new DsROTEntry(m_FilterGraph);
#endif

            try
            {
                // Get the ICaptureGraphBuilder2
                capGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();

                // Start building the graph
                hr = capGraph.SetFiltergraph(m_FilterGraph);
                Marshal.ThrowExceptionForHR(hr);




                Guid CLSID_RtpSource = new Guid("158C4421-945F-4826-8851-2459D92CCF07");
                rtpSource = (RtpFilters.IRtpSource)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_RtpSource, true));
                rtpSource.Initialize(rtpStream);
                rtpSrcFilter = (IBaseFilter)rtpSource;

                hr = m_FilterGraph.AddFilter(rtpSrcFilter, "RtpSource");
                Marshal.ThrowExceptionForHR(hr);

                render = FilterGraphTools.AddFilterByName((IGraphBuilder)m_FilterGraph, FilterCategory.AudioRendererCategory, "Default WaveOut Device");

                hr = capGraph.RenderStream(null, null, rtpSrcFilter, null, render);
                Marshal.ThrowExceptionForHR(hr);



                m_mediaCtrl = m_FilterGraph as IMediaControl;
            }
            catch (Exception ex)
            {

            }
            finally
            {
                if (rtpSrcFilter != null)
                {
                    Marshal.ReleaseComObject(rtpSrcFilter);
                    rtpSrcFilter = null;
                }
                if (render != null)
                {
                    Marshal.ReleaseComObject(render);
                    render = null;
                }
                if (rtpSource != null)
                {
                    Marshal.ReleaseComObject(rtpSource);
                    rtpSource = null;
                }
                if (capGraph != null)
                {
                    Marshal.ReleaseComObject(capGraph);
                    capGraph = null;
                }
            }
        }




        /// <summary> Shut down capture </summary>
        private void CloseInterfaces()
        {
            int hr;

            try
            {
                if (m_mediaCtrl != null)
                {
                    // Stop the graph
                    hr = m_mediaCtrl.Stop();
                    m_bRunning = false;
                }
            }
            catch
            {
            }

#if DEBUG
            // Remove graph from the ROT
            if (m_rot != null)
            {
                m_rot.Dispose();
                m_rot = null;
            }
#endif

            if (m_FilterGraph != null)
            {
                Marshal.ReleaseComObject(m_FilterGraph);
                m_FilterGraph = null;
            }
        }
    }

}